home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
051-075
/
scopedisk51
/
fastdisk
/
fd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-18
|
25KB
|
1,054 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/trackdisk.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>
/* Diskspezifische Daten */
#define NUMHEADS 2
#define BLOCKSIZE TD_SECTOR
#define SIZE (BLOCKSIZE/4)
#define NUM_ENTRIES (SIZE-51-5)
#define NUMBLOCKS (NUMCYLS * NUMHEADS * NUMSECS)
#define ROOTBLOCK (NUMBLOCKS / 2)
#define NUMLONGS (NUMBLOCKS / 32)
#define SECS_PER_TRACK (NUMSECS * NUMHEADS)
/* Diskblockparameter */
#define TYPE 0
#define HEADER_KEY 1
#define HIGHEST_SEQ 2
#define SEQ_NUM 2
#define BLOCK_COUNT 2
#define DATA_SIZE 3
#define FIRST_DATA 4
#define NEXT_DATA 4
#define CHECKSUM 5
#define DIR_HASHTAB 6
#define FH_ENDLIST 6
#define FH_BLOCKLIST (SIZE-51)
#define BITMAPINDEX (SIZE-49)
#define NAME (SIZE-20)
#define CREATE_TICKS (SIZE-5)
#define HASHCHAIN (SIZE-4)
#define PARENT (SIZE-3)
#define EXTENSION (SIZE-2)
#define SECONDARY_TYPE (SIZE-1)
#define BITMAP_CHECKSUM 0
#define NAMEOFFSET NAME*4+1
#define NAMELENGTH NAME*4
/* Diskblock-Typ Definitionen */
#define T_SHORT 2
#define T_DATA 8
#define T_LIST 16
#define ST_ROOT 1
#define ST_DIR 2
#define ST_FILE -3
#define EMPTY (unsigned long*) 0
#define BLOCKED (unsigned long*) 0xFFFFFFFF
#define SOURCE 0
#define DESTINATION 1
/* verwendete Betriebssytemroutinen : exec.library */
extern void *AllocMem();
extern void CloseLibrary();
extern struct IOExtTD *CreateExtIO();
extern struct MsgPort *CreatePort();
extern void DeleteExtIO();
extern void DeletePort();
extern void DoIO();
extern void FreeMem();
extern long OpenDevice();
extern struct Library *OpenLibrary();
extern void SendIO();
extern void WaitIO();
/* verwendete Betriebssytemroutinen : icon.library */
extern struct DiskObject GetDiskObjekt();
extern char* FindToolType();
extern void FreeDiskObject();
/* verwendete Betriebssytemroutinen : dos.library */
extern struct MsgPort *DeviceProc();
/* Unsere Workbenchmessage (von Aztec vordefiniert) */
extern struct WBStartup *WBenchMsg;
/* Globale Variablen */
struct Library *IconBase;
struct IOExtTD *diskreq0,*diskreq1,*diskreq2;
struct MsgPort *diskport;
struct DiskObject *dop;
unsigned long diskchangecount0,diskchangecount1;
unsigned long dirstack [NUMBLOCKS];
unsigned long sectormap [NUMBLOCKS];
unsigned long *buffermap [NUMBLOCKS];
unsigned long *readmap [NUMBLOCKS];
unsigned long filestack [NUMBLOCKS/2];
unsigned short trackmap [NUMTRACKS];
unsigned short dirstackptr = 0,filestackptr = 0,smptr = ROOTBLOCK;
unsigned short wbflag = 0, formatflag = 1, fastloadflag = 1;
unsigned long seccount, rootoff = 2;
unsigned long *trackbuffer;
unsigned long *oldbuffer = NULL;
unsigned long sourcedrive = 0 ,destinationdrive = 1;
char sourcedevice[5] = "DF0:";
char destdevice[5] = "DF1:";
/* Interne Funktionen */
unsigned long popdir(), popfile(), getfreesector();
unsigned long *allocbuffer();
unsigned long *GetSector();
short is_special();
main(argc,argv)
register int argc;
register char *argv[];
{
register short int drivetype,i;
register char *str;
drivetype = SOURCE;
if (argc) {
/* Aufruf vom CLI */
for (i=1; i < argc; i++) {
if (scmp(argv[i],"NOFORMAT",8)) {
formatflag = 0;
} else if (scmp(argv[i],"FASTDIR",7)) {
fastloadflag = 0;
} else if (scmp(argv[i],"FROM",4)) {
drivetype = SOURCE;
} else if (scmp(argv[i],"TO",2)) {
drivetype = DESTINATION;
} else if (scmp(argv[i],"DF",2)) {
if (drivetype == SOURCE) {
sourcedrive = (ULONG) atoi(argv[i]+2);
drivetype = DESTINATION;
} else {
destinationdrive = (ULONG) atoi(argv[i]+2);
}
} else {
printf("Usage : %s [FROM] drive [TO] drive [NOFORMAT] [FASTDIR]\n",argv[0]);
printf("Defaults: FROM df0: TO df1:\n");
exit(0);
}
}
} else {
/* Aufruf von Workbench */
wbflag = 1;
if (!(IconBase = OpenLibrary(ICONNAME,0L))) {
printf("Where is the Icon-Library ?\n");
error();
}
if (!(dop = GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name))) {
printf("Couldn't find Disk-Object!\n");
error();
}
if (str = FindToolType(dop -> do_ToolTypes, "NOFORMAT")) {
if (scmp(str,"ON",2)) {
formatflag = 0;
}
}
if (str = FindToolType(dop -> do_ToolTypes, "FASTDIR")) {
if (scmp(str,"ON",2)) {
fastloadflag = 0;
}
}
if (str = FindToolType(dop -> do_ToolTypes, "FROM")) {
if (scmp(str,"DF",2)) {
sourcedrive = (ULONG) atoi(str+2);
}
}
if (str = FindToolType(dop -> do_ToolTypes, "TO")) {
if (scmp(str,"DF",2)) {
destinationdrive = (ULONG) atoi(str+2);
}
}
FreeDiskObject(dop);
}
sourcedevice[2] = (char) ('0' + (char) sourcedrive);
destdevice[2] = (char) ('0' + (char) destinationdrive);
if (sourcedrive == destinationdrive) {
printf("Can't copy from df%1ld: to df%1ld: !\n");
error();
}
openall ();
printf("\n
FastDisk V1.5
- Written 1987 by Torsten Stolpmann
\n\n");
printf(" Please insert SOURCE Disk in Drive df%1ld:\n",sourcedrive);
printf(" Please insert DESTINATION Disk in Drive df%1ld:\n",destinationdrive);
printf(" Press RETURN to continue\n");
getchar();
checkdisks();
init ();
travel (ROOTBLOCK);
moveblock ();
sortfiles ();
makefiles ();
makedirs ();
makeroot ();
writeheaders ();
writeblank();
writeboot ();
closeall ();
}
travel(head)
unsigned long head;
{
register unsigned long *headbuffer,*workbuffer,*auxbuffer;
register unsigned long sector,hc;
register unsigned short i,count;
/* Rekursives Durchlaufen des Directory-Trees in Zwischenordnung */
headbuffer = buffermap[head];
for (i=DIR_HASHTAB; i<=FH_BLOCKLIST; i++) {
sector=headbuffer[i];
if (sector) {
workbuffer = buffermap[sector] = GetSector(sector);
if ((workbuffer[TYPE] == T_SHORT) &&
(workbuffer[SECONDARY_TYPE] == ST_DIR)) {
if (fastloadflag) {
sectormap[sector] = ROOTBLOCK+2+dirstackptr;
} else {
sectormap[sector] = smptr++;
}
pushdir(sector);
travel(sector);
}
else {
sectormap[sector] = smptr++;
pushfile(sector);
/* Existieren File List Blocks ? */
auxbuffer = buffermap[sector];
count = workbuffer[HIGHEST_SEQ];
while (auxbuffer[EXTENSION]) {
sector = auxbuffer[EXTENSION];
auxbuffer = buffermap[sector] = GetSector(sector);
count += auxbuffer[BLOCK_COUNT];
sectormap[sector] = smptr++;
}
/* Ist es ein .info-File? */
if (is_special(workbuffer)) {
sectormap[workbuffer[FIRST_DATA]] = smptr;
smptr += count;
}
}
/* Weitere Header-Blocks in der Hashchain ? */
hc=workbuffer[HASHCHAIN];
while (hc) {
workbuffer = buffermap[hc] = GetSector(hc);
if ((workbuffer[TYPE] == T_SHORT) &&
(workbuffer[SECONDARY_TYPE] == ST_DIR)) {
sectormap[hc] = ROOTBLOCK+2+dirstackptr;
if (fastloadflag) {
sectormap[hc] = ROOTBLOCK+2+dirstackptr;
} else {
sectormap[hc] = smptr++;
}
pushdir(hc);
travel(hc);
}
else {
sectormap[hc]=smptr++;
pushfile(hc);
/* Existieren File List Blocks ? */
auxbuffer = buffermap[hc];
count = workbuffer[HIGHEST_SEQ];
while (auxbuffer[EXTENSION]) {
sector = auxbuffer[EXTENSION];
auxbuffer = buffermap[sector] = GetSector(sector);
count += auxbuffer[BLOCK_COUNT];
sectormap[sector] = smptr++;
}
/* Ist es ein .info-File ? */
if (is_special(workbuffer)) {
sectormap[workbuffer[FIRST_DATA]] = smptr;
smptr += count;
}
}
hc=workbuffer[HASHCHAIN];
}
}
}
}
moveblock()
{
register unsigned long sector,dest;
register unsigned short diff;
/* Zentriert die Header-Blocks auf der Diskette */
if ((diff = (smptr-1-ROOTBLOCK)/SECS_PER_TRACK) > 2) {
diff = (((diff/2)+1) * SECS_PER_TRACK) - 2;
} else {
diff = 0;
}
if (fastloadflag) {
rootoff += dirstackptr;
diff -= dirstackptr;
}
for (sector=2; sector < NUMBLOCKS; ++sector) {
dest = sectormap[sector];
if ((dest)
&& (dest != ROOTBLOCK)
&& (dest != ROOTBLOCK+1)
&& !((fastloadflag) &&
(buffermap[sector][SECONDARY_TYPE] == ST_DIR))) {
if ((dest >= ROOTBLOCK+2) && (dest-diff < ROOTBLOCK+rootoff)) {
sectormap[sector] -= (ULONG) (diff+rootoff);
} else {
sectormap[sector] -= (ULONG) diff; }
}
}
seccount = (ULONG) ROOTBLOCK - diff;
}
sortfiles()
{
register short int file,count,top;
register unsigned long temp;
/* Erst die .info-Files kopieren */
top = filestackptr-1;
for (file = 0; file < top;file++) {
if (is_special(buffermap[filestack[file]])) {
temp = filestack[file];
for (count=file; count < top; count++) {
filestack[count] = filestack[count+1];
}
filestack[top--] = temp;
file--;
}
}
}
short scmp(s1,s2,len)
register char *s1, *s2;
register short len;
{
register short i;
/* strcmp() ohne Beachtung von Upper-/Lower-Case */
for (i=0; i <len; i++) {
if (toupper(*(s1++)) != *(s2++)) {
return (0);
}
}
return (1);
}
short is_special(buffer)
register unsigned char *buffer;
{
/* Diese Files werden direkt hinter ihrem Headerblock abgelegt */
if (fastloadflag) {
return (1);
}
if (scmp(buffer+NAMEOFFSET+buffer[NAMELENGTH]-5,".INFO",5)) {
return (1);
}
if (scmp(buffer+NAMEOFFSET,"SYSTEM-CONFIGURATION",20)) {
return (1);
}
if (scmp(buffer+NAMEOFFSET,"STARTUP-SEQUENCE",16)) {
return (1);
}
return (0);
}
unsigned long getfreesector()
{
/* Liefert naechsten freier Sector auf der Diskette */
if (seccount == 2) {
return (seccount = NUMBLOCKS-1);
} else {
return (--seccount);
}
}
makefiles()
{
register unsigned long file;
/* kopiert alle File-Datenblocks auf die Zieldiskette.
Die neuen Sectorpositionen werden in den Headerblocks korrigiert. */
while (file = popfile()) {
dofile(buffermap[file]);
}
}
dofile(headbuffer)
register unsigned long *headbuffer;
{
register unsigned long *workbuffer;
register unsigned long sector,next_sector,more_to_come;
if (headbuffer[FIRST_DATA]) {
workbuffer = GetSector(headbuffer[FIRST_DATA]);
if (is_special(headbuffer)) {
sector = sectormap[headbuffer[FIRST_DATA]];
if (sector == ROOTBLOCK) {
sector += rootoff;
}
} else {
sector = getfreesector();
}
sectormap[headbuffer[FIRST_DATA]] = sector;
do {
workbuffer[HEADER_KEY]=sectormap[headbuffer[HEADER_KEY]];
more_to_come = workbuffer[NEXT_DATA];
if (more_to_come) {
if (is_special(headbuffer)) {
next_sector = sector + 1;
if (next_sector == ROOTBLOCK) {
next_sector += rootoff;
}
} else {
next_sector = getfreesector();
}
workbuffer[NEXT_DATA] = next_sector;
}
DoCheckSum(workbuffer,CHECKSUM);
PutSector(sector,workbuffer);
if (more_to_come) {
workbuffer = GetSector(more_to_come);
sector = sectormap[more_to_come] = next_sector;
}
} while (more_to_come);
}
/* Aenderungen in File Header & File List Blocks */
do {
more_to_come = headbuffer[EXTENSION];
sector = FH_BLOCKLIST;
while (sector >= FH_ENDLIST) {
headbuffer[sector--]=sectormap[headbuffer[sector]];
}
headbuffer[PARENT] = sectormap[headbuffer[PARENT]];
headbuffer[HEADER_KEY] = sectormap[headbuffer[HEADER_KEY]];
headbuffer[FIRST_DATA] = sectormap[headbuffer[FIRST_DATA]];
headbuffer[HASHCHAIN] = sectormap[headbuffer[HASHCHAIN]];
headbuffer[EXTENSION] = sectormap[headbuffer[EXTENSION]];
DoCheckSum(headbuffer,CHECKSUM);
if (more_to_come) {
headbuffer = buffermap[more_to_come];
}
} while (more_to_come);
}
makedirs()
{
register unsigned long *headbuffer, sector, dir;
/* Aenderungen in den Directory-Header Blocks */
while (dir = popdir()) {
headbuffer = buffermap[dir];
for ( sector = FH_BLOCKLIST;
sector >= FH_ENDLIST;
--sector) {
if (headbuffer[sector]) {
headbuffer[sector]=sectormap[headbuffer[sector]];
}
}
headbuffer[PARENT] = sectormap[headbuffer[PARENT]];
headbuffer[HEADER_KEY] = sectormap[headbuffer[HEADER_KEY]];
headbuffer[HASHCHAIN] = sectormap[headbuffer[HASHCHAIN]];
headbuffer[EXTENSION] = sectormap[headbuffer[EXTENSION]];
DoCheckSum(headbuffer,CHECKSUM);
}
}
makeroot()
{
register unsigned long *headbuffer,*workbuffer;
register unsigned long sector;
register unsigned long bmsector,mask;
register unsigned short offset,count;
workbuffer = allocbuffer();
headbuffer = buffermap[ROOTBLOCK];
/* Aenderungen im Rootblock */
bmsector = sectormap[headbuffer[BITMAPINDEX]];
for ( sector = FH_BLOCKLIST; sector >= FH_ENDLIST; --sector) {
if (headbuffer[sector]) {
headbuffer[sector]=sectormap[headbuffer[sector]];
}
}
headbuffer[BITMAPINDEX] = bmsector;
headbuffer[CREATE_TICKS] += 1; /* Wichtig ! Hiermit wird gesichert, */
/* dass AmigaDOS Quell- und Zieldisk */
/* unterscheiden kann. */
DoCheckSum(headbuffer,CHECKSUM);
/* Neuen Bit-Map Sector erstellen */
for (count=1; count <= NUMLONGS; ++count) {
workbuffer[count] = 0xFFFFFFFF;
}
for (count = 2; count < NUMBLOCKS; ++count) {
sector = sectormap[count];
if (sector) {
offset = 1 + ((sector-2)/32);
mask = (ULONG) 1 << ((sector-2) & 0x1f);
workbuffer[offset] -= (ULONG) mask;
}
}
DoCheckSum(workbuffer,BITMAP_CHECKSUM);
PutSector(bmsector,workbuffer);
}
writeheaders()
{
register unsigned short buffer;
/* Alle Header-Blocks werden auf Zieldisk geschrieben */
for (buffer=0; buffer<NUMBLOCKS; ++buffer) {
dirstack[buffer] = NULL;
}
for (buffer = 2; buffer<NUMBLOCKS; ++buffer) {
if (buffermap[buffer]) {
dirstack[sectormap[buffer]] = (ULONG) buffermap[buffer];
buffermap[buffer] = NULL;
}
}
for (buffer = 0; buffer<NUMBLOCKS; ++buffer) {
if (dirstack[buffer]) {
PutSector((ULONG) buffer,dirstack[buffer]);
}
}
PutSector(NULL,NULL);
}
writeblank()
{
register short int i;
/* Formatiert nicht belegte Tracks auf der Zieldisk */
if (formatflag) {
for (i=0; i < NUMTRACKS; i++) {
if ( !(trackmap[i])) {
formattrack(i);
WaitIO(diskreq2);
trackmap[i]=1;
}
}
}
}
writeboot()
{
register unsigned long *workbuffer;
/* Bootsectoren uebertragen */
workbuffer = allocbuffer();
ReadSector (0L,workbuffer);
WriteSector(0L,workbuffer);
WaitIO(diskreq1);
ReadSector (1L,workbuffer);
WriteSector(1L,workbuffer);
WaitIO(diskreq1);
diskreq1 -> iotd_Req.io_Command = ETD_UPDATE;
diskreq1 -> iotd_Count = diskchangecount1;
DoIO (diskreq1);
releasebuffer(workbuffer);
}
init()
{
register unsigned long *headbuffer,*workbuffer,*buffer;
register unsigned long count,offset,mask;
/* Feldinitialisierungen */
for (count=0L; count < NUMBLOCKS; ++count) {
sectormap [count] = NULL;
buffermap [count] = NULL;
dirstack [count] = NULL;
readmap [count] = EMPTY;
}
sectormap[0] = 0L;
sectormap[1] = 1L;
/* Trackbuffer */
for (count=0; count <= NUMTRACKS; count++) {
trackmap[count] = 0;
}
if ( !(trackbuffer = AllocMem(NUMSECS * BLOCKSIZE, MEMF_CHIP | MEMF_CLEAR))) {
printf("Can't allocate Trackbuffer !\n");
error();
}
/* Rootblock laden */
smptr = ROOTBLOCK;
headbuffer = buffermap[ROOTBLOCK] = GetSector(ROOTBLOCK);
sectormap[ROOTBLOCK] = smptr++;
sectormap[headbuffer[BITMAPINDEX]] = smptr++;
/* Markieren aller nicht belegter Bloecke (BAM-Selection) */
workbuffer = GetSector(headbuffer[BITMAPINDEX]);
for (count = 2L; count < NUMBLOCKS; ++count) {
offset = 1L + ((count-2L)/32L);
mask = 1L << ((count-2L) & 0x1fL);
if (workbuffer[offset] & mask) {
if (readmap[count]) {
releasebuffer(readmap[count]);
}
readmap[count] = BLOCKED;
}
}
readmap[ROOTBLOCK] = readmap[headbuffer[BITMAPINDEX]] = BLOCKED;
readmap[0] = readmap[1] = BLOCKED;
releasebuffer(workbuffer);
}
pushdir(sector)
register unsigned long sector;
{
dirstack[dirstackptr++] = sector;
}
unsigned long popdir()
{
if ((dirstackptr) == 0)
return (NULL);
else
return (dirstack[--dirstackptr]);
}
pushfile(sector)
register unsigned long sector;
{
filestack[filestackptr++] = sector;
}
unsigned long popfile()
{
if ((filestackptr) == 0)
return (NULL);
else
return (filestack[--filestackptr]);
}
DoCheckSum(buffer,pos)
register unsigned long *buffer;
register unsigned short pos;
{
register unsigned long count;
register unsigned long checksum;
/* CheckSum fuer normale und Bit-Map Blocks errechnen */
buffer[pos] = checksum = NULL;
for (count=0; count < SIZE; ++count) {
checksum += (unsigned long) buffer[count];
}
buffer[pos] -= (unsigned long) checksum;
}
ReadSector (sector,buffer)
register unsigned long sector,*buffer;
{
unsigned long offset = sector * BLOCKSIZE;
/* Laedt einen Sector von der Quell-Diskette */
diskreq0 -> iotd_Req.io_Length = BLOCKSIZE;
diskreq0 -> iotd_Req.io_Data = (APTR) buffer;
diskreq0 -> iotd_Req.io_Command = ETD_READ;
diskreq0 -> iotd_Count = diskchangecount0;
diskreq0 -> iotd_Req.io_Offset = offset;
DoIO (diskreq0);
if (diskreq0 -> iotd_Req.io_Error) {
printf("Error %d while reading sector %4d from drive df%1ld: !\n",
(BYTE) diskreq0 -> iotd_Req.io_Error,
sector, sourcedrive);
error();
}
}
unsigned long *GetSector(sector)
register unsigned long sector;
{
register unsigned long *workbuffer,*temp;
register unsigned long track,sec;
/* Holt einen Sector von der Quell-Diskette oder */
/* liefert den entsprechenden Buffer. */
Chk_Abort();
if (sector >= NUMBLOCKS) {
printf("Illegal sector detected, Disk in drive df%1ld: is corrupt !\n",
sourcedrive);
printf("Use diskdoctor to correct this disk.\n");
error();
}
if (readmap[sector]) {
if (readmap[sector] == BLOCKED) {
printf("Double Reference to sector %ld, disk in df%1ld: is corrupt !\n",
sector,sourcedrive);
printf("Use diskdoctor to correct this disk.\n");
error();
} else {
temp = readmap[sector];
readmap[sector] = BLOCKED;
return (temp);
}
} else {
workbuffer = allocbuffer();
ReadSector (sector,workbuffer);
readmap[sector] = BLOCKED;
track = sector / SECS_PER_TRACK;
for (sec=track*SECS_PER_TRACK; sec < (track+1)*SECS_PER_TRACK; sec++) {
if (readmap[sec] == EMPTY) {
if (readmap[sec] = allocbuffer()) {
ReadSector(sec,readmap[sec]);
} else {
break;
}
}
}
return (workbuffer);
}
}
formattrack(track)
register short int track;
{
/* Formatiert einen Track auf der Zieldiskette */
Chk_Abort();
diskreq2 -> iotd_Req.io_Length = NUMSECS * BLOCKSIZE;
diskreq2 -> iotd_Req.io_Data = (APTR) trackbuffer;
diskreq2 -> iotd_Req.io_Command = TD_FORMAT;
diskreq2 -> iotd_Count = diskchangecount1;
diskreq2 -> iotd_Req.io_Offset = track * NUMSECS * BLOCKSIZE;
SendIO (diskreq2);
if (diskreq1 -> iotd_Req.io_Error) {
printf("Error %ud while formatting Cylinder %2ud on Drive df%1ld: !\n",
(BYTE) diskreq2 -> iotd_Req.io_Error,
track/2, destinationdrive);
error();
}
}
WriteSector(sector,buffer)
register unsigned long sector;
register unsigned long *buffer;
{
register unsigned long offset = sector * BLOCKSIZE;
register short int track;
/* Falls noch nicht geschehen, formatieren des Ziel-Tracks */
track = (sector / NUMSECS);
if ( (formatflag) && !(trackmap[track])) {
formattrack(track);
trackmap[track] = 1;
}
/* Schreibt einen Sector auf die Ziel-Diskette */
diskreq1 -> iotd_Req.io_Length = BLOCKSIZE;
diskreq1 -> iotd_Req.io_Data = (APTR) buffer;
diskreq1 -> iotd_Req.io_Command = ETD_WRITE;
diskreq1 -> iotd_Count = diskchangecount1;
diskreq1 -> iotd_Req.io_Offset = offset;
SendIO (diskreq1); /* Asynchroner Schreibzugriff */
}
PutSector(sector,buffer)
register unsigned long sector;
register unsigned long *buffer;
{
/* Schreibt Sector auf Zieldisk und deallociert den Buffer */
if (oldbuffer) {
WaitIO(diskreq1); /* Warten auf das Ende des letzten Schreibzugriffs */
if (diskreq1 -> iotd_Req.io_Error) {
printf("Error %d while writing Sector %4ld to drive df%1ld: !\n",
(BYTE) diskreq1 -> iotd_Req.io_Error,
sector, destinationdrive);
error();
}
releasebuffer(oldbuffer);
}
if (oldbuffer = buffer) {
WriteSector(sector, buffer);
}
}
unsigned long *allocbuffer()
{
register unsigned long *buffer;
register short int sec;
/* Allociert 512 Byte Chip-Memory als Sector-Buffer */
/* Falls kein Chip-Mem mehr vorhanden ist, wird ein */
/* bestehender, nicht unbedingt benoetigter Sector */
/* deallociert. */
buffer = AllocMem((long) BLOCKSIZE, MEMF_CHIP);
if (buffer == NULL) {
for (sec=2; sec<NUMBLOCKS; sec++) {
if ((readmap[sec]) &&
(readmap[sec] != BLOCKED) &&
(readmap[sec][TYPE] == T_DATA)) {
buffer = readmap[sec];
readmap[sec] = EMPTY;
break;
}
}
if (sec == NUMBLOCKS) {
printf("Sorry, not enough CHIP-Memory to continue ...\n");
printf("Program terminated unsuccessfully.\n");
error();
}
}
return (buffer);
}
releasebuffer(buffer)
register unsigned long *buffer;
{
/* Deallociert einen 512-Byte Buffer */
if (buffer) {
FreeMem(buffer, (long) BLOCKSIZE);
}
}
openall()
{
register unsigned long err;
/* Oeffnen der Disk-Devices */
if ( !(diskport = CreatePort (NULL, NULL))) {
printf("Can't create DiskPort !\n");
error();
}
if ( !(diskreq0 = CreateExtIO (diskport, (long) sizeof (*diskreq0)))) {
printf("Can't make IO block !\n");
error();
}
if ( !(diskreq1 = CreateExtIO (diskport, (long) sizeof (*diskreq1)))) {
printf("Can't make IO block !\n");
error();
}
if ( !(diskreq2 = CreateExtIO (diskport, (long) sizeof (*diskreq2)))) {
printf("Can't make IO block !\n");
error();
}
if (err = OpenDevice (TD_NAME, sourcedrive, diskreq0, NULL)) {
printf ("Can't get drive %1ld, Error %ld.\n", sourcedrive, err);
error();
}
if (err = OpenDevice (TD_NAME, destinationdrive, diskreq1, NULL)) {
printf ("Can't get drive %1ld, Error %ld\n", destinationdrive, err);
error();
}
if (err = OpenDevice (TD_NAME, destinationdrive, diskreq2, NULL)) {
printf ("Can't get drive %1ld, Error %ld\n", destinationdrive, err);
error();
}
/* Disk-Validation abstellen */
dos_packet(DeviceProc(destdevice), ACTION_INHIBIT,
1L,0L,0L,0L,0L,0L,0L);
dos_packet(DeviceProc(sourcedevice), ACTION_INHIBIT,
1L,0L,0L,0L,0L,0L,0L);
}
checkdisks()
{
diskreq0 -> iotd_Req.io_Command = TD_CHANGESTATE;
DoIO (diskreq0);
if (diskreq0 -> iotd_Req.io_Actual) {
printf("No Disk in Drive %1ld !\n",sourcedrive);
error();
}
diskreq1 -> iotd_Req.io_Command = TD_CHANGESTATE;
DoIO (diskreq1);
if (diskreq1 -> iotd_Req.io_Actual) {
printf("No Disk in Drive %1ld !\n",destinationdrive);
error();
}
diskreq1 -> iotd_Req.io_Command = TD_PROTSTATUS;
DoIO (diskreq1);
if (diskreq1 -> iotd_Req.io_Actual) {
printf("Disk in Drive %1ld is write-protected !\n",destinationdrive);
error();
}
diskreq0 -> iotd_Req.io_Command = TD_CHANGENUM;
DoIO (diskreq0);
diskchangecount0 = diskreq0 -> iotd_Req.io_Actual;
diskreq1 -> iotd_Req.io_Command = TD_CHANGENUM;
DoIO (diskreq1);
diskchangecount1 = diskreq1 -> iotd_Req.io_Actual;
}
Chk_Abort()
{
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
printf("F** BREAK\n");
error();
}
}
error()
{
closeall();
if (wbflag) {
printf("Press Return to abort.\n");
getchar();
}
exit(20);
}
closeall()
{
register unsigned long count;
/* Schliessen der Disk-Devices */
/* Deallocieren der Buffer */
/* Schliessen der Library */
if (oldbuffer) {
releasebuffer(oldbuffer);
}
for (count = NULL; count<NUMBLOCKS; ++count) {
if (buffermap[count]) {
releasebuffer(buffermap[count]);
}
if ((readmap[count]) && (readmap[count] != BLOCKED)) {
releasebuffer(readmap[count]);
}
}
if (trackbuffer) {
FreeMem(trackbuffer,NUMSECS * BLOCKSIZE);
}
if (diskreq0) {
if (((long) diskreq0 -> iotd_Req.io_Device != -1L) &&
((long) diskreq0 -> iotd_Req.io_Device != 0L)) {
CloseDevice (diskreq0);
}
DeleteExtIO (diskreq0, (long) sizeof (*diskreq0));
}
if (diskreq1) {
if (((long) diskreq1 -> iotd_Req.io_Device != -1L) &&
((long) diskreq1 -> iotd_Req.io_Device != 0L)) {
CloseDevice (diskreq1);
/* Forced Diskchange im Destinationdrive */
dos_packet(DeviceProc(destdevice), ACTION_INHIBIT,
0L,0L,0L,0L,0L,0L,0L);
dos_packet(DeviceProc(sourcedevice), ACTION_INHIBIT,
0L,0L,0L,0L,0L,0L,0L);
}
DeleteExtIO (diskreq1, (long) sizeof (*diskreq1));
}
if (diskreq2) {
if (((long) diskreq1 -> iotd_Req.io_Device != -1L) &&
((long) diskreq1 -> iotd_Req.io_Device != 0L)) {
CloseDevice (diskreq2);
}
DeleteExtIO (diskreq2, (long) sizeof (*diskreq2));
}
if (diskport) {
DeletePort (diskport);
}
if (IconBase) {
CloseLibrary(IconBase);
}
}